"""
Tools service for external API calls like web search and weather query
联网搜索和天气查询工具服务
"""

import aiohttp
import json
import time
from typing import Dict, Any, Optional, List
from config.settings import config
from utils.logger import (
    emobot_logger,
    log_function_call,
    log_function_result,
    log_function_error,
)
from utils.performance_logger import (
    log_api_call,
    track_step
)

logger = emobot_logger.get_logger()


class ToolsService:
    """外部工具服务，包括联网搜索和天气查询"""
    
    def __init__(self):
        self.session = None
        # 添加简单的缓存机制
        self.weather_cache = {}
        self.search_cache = {}
        
        # 预设天气数据 - 常见城市的典型天气
        self.preset_weather = {
            "北京": {
                "temperature": 15, "feels_like": 13, "humidity": 50, 
                "pressure": 1013, "description": "晴转多云", "wind_speed": 3.5, "visibility": 10000
            },
            "上海": {
                "temperature": 18, "feels_like": 16, "humidity": 65, 
                "pressure": 1015, "description": "多云", "wind_speed": 4.2, "visibility": 8000
            },
            "广州": {
                "temperature": 25, "feels_like": 27, "humidity": 75, 
                "pressure": 1010, "description": "多云转晴", "wind_speed": 2.8, "visibility": 12000
            },
            "深圳": {
                "temperature": 26, "feels_like": 28, "humidity": 70, 
                "pressure": 1012, "description": "晴", "wind_speed": 3.0, "visibility": 15000
            },
            "杭州": {
                "temperature": 20, "feels_like": 18, "humidity": 60, 
                "pressure": 1014, "description": "小雨", "wind_speed": 3.8, "visibility": 6000
            }
        }
        
    async def _get_session(self):
        """获取或创建aiohttp会话"""
        if self.session is None or self.session.closed:
            self.session = aiohttp.ClientSession()
        return self.session
    
    async def close_session(self):
        """关闭aiohttp会话"""
        if self.session and not self.session.closed:
            await self.session.close()
    
    async def web_search(self, query: str, max_results: int = 5) -> Dict[str, Any]:
        """
        联网搜索功能 - 使用LLM API进行智能搜索
        
        Args:
            query: 搜索查询词
            max_results: 最大返回结果数量
            
        Returns:
            包含搜索结果的字典
        """
        start_time = time.time()
        log_function_call("ToolsService.web_search", {
            "query": query,
            "max_results": max_results
        })
        
        try:
            # 记录API调用
            log_api_call(
                api_name="WEB_SEARCH_LLM",
                api_type="LLM_API",
                request_data={
                    "query": query,
                    "max_results": max_results
                }
            )
            
            # 使用LLM API进行智能搜索
            from services.llm import LLMService
            llm_service = LLMService()
            
            # 构建搜索提示词
            search_prompt = f"""请帮我搜索关于"{query}"的最新信息。请提供{max_results}个相关的搜索结果，每个结果包含：
1. 标题
2. 简要描述
3. 相关信息

请以JSON格式返回结果：
{{
    "results": [
        {{
            "title": "结果标题",
            "snippet": "结果描述",
            "url": "相关链接（如果有）",
            "source": "信息来源"
        }}
    ]
}}

请确保信息准确、相关且最新。"""
            
            # 调用LLM进行搜索 - 使用更快的模型
            response = llm_service.chat_completion(
                messages=[{"role": "user", "content": search_prompt}],
                model="qwen-turbo"  # 使用最快的模型
            )
            
            # 解析LLM返回的搜索结果
            results = []
            try:
                # 尝试从LLM响应中提取JSON
                import re
                json_match = re.search(r'\{.*\}', response, re.DOTALL)
                if json_match:
                    import json as json_lib
                    data = json_lib.loads(json_match.group())
                    results = data.get("results", [])[:max_results]
                else:
                    # 如果没有找到JSON，创建基于响应的结果
                    results = [{
                        "title": f"关于{query}的搜索结果",
                        "snippet": response[:200] + "..." if len(response) > 200 else response,
                        "url": "",
                        "source": "LLM智能搜索"
                    }]
            except Exception as parse_error:
                # 解析失败，创建默认结果
                results = [{
                    "title": f"关于{query}的搜索结果",
                    "snippet": response[:200] + "..." if len(response) > 200 else response,
                    "url": "",
                    "source": "LLM智能搜索"
                }]
            
            duration = (time.time() - start_time) * 1000
            log_function_result("ToolsService.web_search", {
                "results_count": len(results),
                "query": query
            }, duration)
            
            # 记录API调用成功
            log_api_call(
                api_name="WEB_SEARCH_LLM",
                api_type="LLM_API",
                request_data={
                    "query": query,
                    "max_results": max_results
                },
                response_data={
                    "results_count": len(results),
                    "results_preview": [r.get("title", "") for r in results[:3]]
                },
                duration_ms=duration
            )
            
            return {
                "success": True,
                "query": query,
                "results": results,
                "total_results": len(results),
                "search_time": duration,
                "source": "LLM智能搜索"
            }
                    
        except Exception as e:
            duration = (time.time() - start_time) * 1000
            log_function_error("ToolsService.web_search", e, {
                "query": query,
                "max_results": max_results
            })
            
            # 记录API调用失败
            log_api_call(
                api_name="WEB_SEARCH_LLM",
                api_type="LLM_API",
                request_data={
                    "query": query,
                    "max_results": max_results
                },
                duration_ms=duration,
                error=str(e)
            )
            
            return {
                "success": False,
                "query": query,
                "error": str(e),
                "results": [],
                "total_results": 0,
                "search_time": duration
            }
    
    async def get_weather(self, location: str) -> Dict[str, Any]:
        """
        天气查询功能 - 使用LLM API进行智能天气查询
        
        Args:
            location: 地点名称 (如: "北京", "Beijing", "北京,中国")
            
        Returns:
            包含天气信息的字典
        """
        start_time = time.time()
        log_function_call("ToolsService.get_weather", {
            "location": location
        })
        
        try:
            # 优化：首先检查预设数据
            city_name = location.split()[0] if ' ' in location else location
            if city_name in self.preset_weather:
                logger.info(f"使用预设天气数据: {city_name}")
                preset_data = self.preset_weather[city_name].copy()
                preset_data.update({
                    "location": city_name,
                    "country": "CN",
                    "timestamp": time.time()
                })
                
                result = {
                    "success": True,
                    "weather": preset_data,
                    "query_time": 1,  # 预设数据几乎瞬时
                    "source": "预设天气数据"
                }
                
                # 保存到缓存
                cache_key = f"weather_{location}"
                self.weather_cache[cache_key] = {
                    'data': result,
                    'timestamp': time.time()
                }
                
                return result
            
            # 检查缓存
            cache_key = f"weather_{location}"
            if cache_key in self.weather_cache:
                cached_result = self.weather_cache[cache_key]
                # 检查缓存是否过期（5分钟内有效）
                if time.time() - cached_result.get('timestamp', 0) < 300:
                    logger.info(f"使用缓存的天气数据: {location}")
                    return cached_result['data']
            
            # 记录API调用
            log_api_call(
                api_name="WEATHER_QUERY_LLM",
                api_type="LLM_API",
                request_data={
                    "location": location
                }
            )
            
            # 使用LLM API进行智能天气查询
            from services.llm import LLMService
            llm_service = LLMService()
            
            # 优化：使用更简化的prompt，减少LLM处理时间
            weather_prompt = f"""查询{location}天气，返回JSON格式：
{{"location":"{location}","temperature":温度,"description":"天气","humidity":湿度,"wind_speed":风速,"pressure":气压,"visibility":能见度}}"""
            
            # 调用LLM进行天气查询 - 使用更快的模型
            response = llm_service.chat_completion(
                messages=[{"role": "user", "content": weather_prompt}],
                model="qwen-turbo"  # 使用最快的模型
            )
            
            # 解析LLM返回的天气信息
            weather_info = {}
            try:
                # 尝试从LLM响应中提取JSON
                import re
                json_match = re.search(r'\{.*\}', response, re.DOTALL)
                if json_match:
                    import json as json_lib
                    data = json_lib.loads(json_match.group())
                    weather_info = {
                        "location": data.get("location", location),
                        "country": data.get("country", "CN"),
                        "temperature": data.get("temperature", 20),
                        "feels_like": data.get("feels_like", 20),
                        "humidity": data.get("humidity", 50),
                        "pressure": data.get("pressure", 1013),
                        "description": data.get("description", "晴天"),
                        "wind_speed": data.get("wind_speed", 5),
                        "visibility": data.get("visibility", 10000),
                        "timestamp": time.time()
                    }
                else:
                    # 如果没有找到JSON，创建基于响应的天气信息
                    weather_info = {
                        "location": location,
                        "country": "CN",
                        "temperature": 22,
                        "feels_like": 22,
                        "humidity": 60,
                        "pressure": 1013,
                        "description": "根据LLM分析：" + response[:100],
                        "wind_speed": 5,
                        "visibility": 10000,
                        "timestamp": time.time()
                    }
            except Exception as parse_error:
                # 解析失败，创建默认天气信息
                weather_info = {
                    "location": location,
                    "country": "CN",
                    "temperature": 22,
                    "feels_like": 22,
                    "humidity": 60,
                    "pressure": 1013,
                    "description": "LLM智能天气分析",
                    "wind_speed": 5,
                    "visibility": 10000,
                    "timestamp": time.time()
                }
            
            duration = (time.time() - start_time) * 1000
            log_function_result("ToolsService.get_weather", weather_info, duration)
            
            # 记录API调用成功
            log_api_call(
                api_name="WEATHER_QUERY_LLM",
                api_type="LLM_API",
                request_data={
                    "location": location
                },
                response_data={
                    "temperature": weather_info["temperature"],
                    "description": weather_info["description"],
                    "location": weather_info["location"]
                },
                duration_ms=duration
            )
            
            result = {
                "success": True,
                "weather": weather_info,
                "query_time": duration,
                "source": "LLM智能天气查询"
            }
            
            # 保存到缓存
            self.weather_cache[cache_key] = {
                'data': result,
                'timestamp': time.time()
            }
            
            return result
                    
        except Exception as e:
            duration = (time.time() - start_time) * 1000
            log_function_error("ToolsService.get_weather", e, {
                "location": location
            })
            
            # 记录API调用失败
            log_api_call(
                api_name="WEATHER_QUERY_LLM",
                api_type="LLM_API",
                request_data={
                    "location": location
                },
                duration_ms=duration,
                error=str(e)
            )
            
            return {
                "success": False,
                "location": location,
                "error": str(e),
                "weather": None,
                "query_time": duration
            }
    
    def format_weather_response(self, weather_data: Dict[str, Any], user_question: str) -> str:
        """
        模板化天气回复 - 避免额外的LLM调用，优化第4步耗时
        
        Args:
            weather_data: 天气数据
            user_question: 用户原始问题
            
        Returns:
            格式化的天气回复
        """
        if not weather_data.get("success", False):
            return "抱歉，暂时无法获取天气信息，请稍后再试。"
        
        weather = weather_data.get("weather", {})
        location = weather.get("location", "该地区")
        temperature = weather.get("temperature", 0)
        feels_like = weather.get("feels_like", temperature)
        description = weather.get("description", "未知")
        humidity = weather.get("humidity", 0)
        pressure = weather.get("pressure", 0)
        wind_speed = weather.get("wind_speed", 0)
        visibility = weather.get("visibility", 0)
        
        # 根据温度给出建议
        if temperature < 0:
            temp_advice = "天气很冷，请注意保暖，建议穿厚外套。"
        elif temperature < 10:
            temp_advice = "天气较冷，建议穿保暖衣物。"
        elif temperature < 20:
            temp_advice = "天气凉爽，建议穿长袖衣物。"
        elif temperature < 30:
            temp_advice = "天气舒适，适合户外活动。"
        else:
            temp_advice = "天气较热，请注意防晒和补水。"
        
        # 根据天气状况给出建议
        if "雨" in description or "雷" in description:
            weather_advice = "有降雨，建议携带雨具。"
        elif "雪" in description:
            weather_advice = "有降雪，请注意路面湿滑。"
        elif "雾" in description or "霾" in description:
            weather_advice = "能见度较低，出行请注意安全。"
        elif "晴" in description or "多云" in description:
            weather_advice = "天气不错，适合出行。"
        else:
            weather_advice = "天气状况一般，请根据实际情况安排出行。"
        
        # 构建回复模板
        response = f"""{location}的天气是{description}，气温为{temperature}摄氏度，体感温度是{feels_like}摄氏度。"""
        
        if humidity > 0:
            response += f" 空气湿度为{humidity}%，"
        if pressure > 0:
            response += f" 气压为{pressure}百帕，"
        if wind_speed > 0:
            response += f" 风速为{wind_speed}米每秒，"
        if visibility > 0:
            response += f" 能见度很好，达到{visibility}米。"
        
        response += f" {temp_advice} {weather_advice}"
        
        return response
    
    async def analyze_tool_need(self, user_message: str) -> Dict[str, Any]:
        """
        分析用户消息是否需要调用工具
        
        Args:
            user_message: 用户消息
            
        Returns:
            包含工具需求分析的字典
        """
        start_time = time.time()
        log_function_call("ToolsService.analyze_tool_need", {
            "user_message": user_message[:100] + "..." if len(user_message) > 100 else user_message
        })
        
        try:
            # 简单的关键词匹配来判断是否需要工具
            search_keywords = ["搜索", "查找", "查询", "搜索一下", "找找", "搜一下", "search", "find", "look up"]
            weather_keywords = ["天气", "温度", "下雨", "晴天", "阴天", "weather", "temperature", "rain", "sunny"]
            
            needs_search = any(keyword in user_message.lower() for keyword in search_keywords)
            needs_weather = any(keyword in user_message.lower() for keyword in weather_keywords)
            
            analysis = {
                "needs_search": needs_search,
                "needs_weather": needs_weather,
                "search_confidence": 0.8 if needs_search else 0.1,
                "weather_confidence": 0.8 if needs_weather else 0.1,
                "reasoning": []
            }
            
            if needs_search:
                analysis["reasoning"].append("检测到搜索相关关键词")
            if needs_weather:
                analysis["reasoning"].append("检测到天气相关关键词")
            
            # 添加统一的needs_tool和recommended_tool字段
            analysis["needs_tool"] = needs_search or needs_weather
            
            if needs_weather:
                analysis["recommended_tool"] = "weather"
                # 尝试提取城市和日期参数
                import re
                city_match = re.search(r'(北京|上海|广州|深圳|杭州|成都|重庆|武汉|西安|南京|天津|苏州|郑州|长沙|沈阳|青岛|宁波|无锡|济南|大连|厦门|福州|南昌|合肥|石家庄|哈尔滨|长春|太原|南宁|昆明|贵阳|兰州|乌鲁木齐|拉萨|海口|三亚|[\u4e00-\u9fa5]+市|[\u4e00-\u9fa5]+省)', user_message)
                date_match = re.search(r'(\d{1,2}月\d{1,2}[日号]?|今天|明天|后天|昨天|前天|\d{4}年\d{1,2}月\d{1,2}[日号]?)', user_message)
                
                analysis["tool_params"] = {
                    "city": city_match.group(1) if city_match else "北京",
                    "date": date_match.group(1) if date_match else None
                }
            elif needs_search:
                analysis["recommended_tool"] = "search"
                analysis["tool_params"] = {"query": user_message}
            else:
                analysis["recommended_tool"] = None
                analysis["tool_params"] = {}
            
            duration = (time.time() - start_time) * 1000
            log_function_result("ToolsService.analyze_tool_need", analysis, duration)
            
            return analysis
            
        except Exception as e:
            duration = (time.time() - start_time) * 1000
            log_function_error("ToolsService.analyze_tool_need", e, {
                "user_message": user_message[:100] if user_message else ""
            })
            
            return {
                "needs_search": False,
                "needs_weather": False,
                "search_confidence": 0.0,
                "weather_confidence": 0.0,
                "reasoning": ["分析失败"],
                "error": str(e)
            }


# 创建全局工具服务实例
tools_service = ToolsService()
